#!/bin/bash
set -e # 如果任何命令以非零状态退出，则立即退出。

echo "--- 开始 C++ 后端 (TaskAPI) CI/CD ---"

# 0. 安装必要的系统依赖 (如果尚未安装)
echo "正在检查并安装系统依赖: pkg-config, zip..."
sudo apt-get update -y
# DEBIAN_FRONTEND=noninteractive 避免在 CI 环境中出现交互式提示
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y pkg-config zip build-essential cmake git

# 导航到工作空间内的 C++ 项目目录
CPP_PROJECT_DIR="./back-end/cpp/TaskAPI" # <--- 根据你的实际项目结构调整
if [ ! -d "$CPP_PROJECT_DIR" ]; then
    echo "错误：C++ 项目目录 '$CPP_PROJECT_DIR' 未找到。"
    echo "当前工作目录是 $(pwd)，请确认路径 '$CPP_PROJECT_DIR' 相对于此路径是正确的。"
    ls -la # 列出当前目录内容以帮助调试
    exit 1
fi
cd "$CPP_PROJECT_DIR"
echo "已切换目录到 $(pwd)"

# 1. 设置 vcpkg (如果不存在则克隆，考虑缓存以提高效率)
echo "正在设置 vcpkg..."
VCPKG_DIR_NAME="vcpkg" # 定义vcpkg目录名，方便引用
if [ ! -d "$VCPKG_DIR_NAME" ]; then
    echo "克隆 vcpkg 仓库..."
    git clone https://github.com/microsoft/vcpkg.git "$VCPKG_DIR_NAME"
    cd "$VCPKG_DIR_NAME"
    # 运行 bootstrap 脚本
    echo "引导 vcpkg..."
    ./bootstrap-vcpkg.sh -disableMetrics
    cd .. # 返回到 CPP_PROJECT_DIR
else
    echo "vcpkg 目录已存在。尝试更新并重新引导..."
    cd "$VCPKG_DIR_NAME"
    echo "当前 vcpkg 目录: $(pwd)"

    # 检查当前分支状态
    current_branch_check=$(git rev-parse --abbrev-ref HEAD)
    if [ "$current_branch_check" = "HEAD" ]; then
        echo "vcpkg 处于 detached HEAD 状态。尝试切换到默认远程分支..."
        # 尝试获取远程的默认分支
        default_remote_branch_on_detached=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5)
        if [ -z "$default_remote_branch_on_detached" ]; then
            echo "警告：无法确定远程 origin 的 HEAD 分支。将尝试使用 master。"
            default_remote_branch_on_detached="master" # 或者尝试 "main"
        fi
        echo "vcpkg 的远程默认分支似乎是: $default_remote_branch_on_detached"
        # 尝试切换到该分支
        if git show-ref --verify --quiet refs/heads/"$default_remote_branch_on_detached"; then
            git checkout "$default_remote_branch_on_detached"
        else
            echo "本地不存在分支 '$default_remote_branch_on_detached'，尝试从远程创建并跟踪..."
            git checkout -b "$default_remote_branch_on_detached" "origin/$default_remote_branch_on_detached" || {
                echo "错误：无法切换到或创建分支 '$default_remote_branch_on_detached'。请检查 vcpkg 仓库状态。"
                exit 1
            }
        fi
    fi

    # 确保本地分支跟踪远程分支
    echo "尝试从远程更新 vcpkg..."
    git fetch origin # 获取所有远程更新，但不合并
    
    # 获取当前所在分支或远程默认分支
    current_local_branch=$(git rev-parse --abbrev-ref HEAD)
    if [ "$current_local_branch" = "HEAD" ]; then # 如果仍然是detached HEAD（不太可能到这里了）
        default_remote_branch=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5)
        if [ -z "$default_remote_branch" ]; then default_remote_branch="master"; fi
    else
        default_remote_branch=$current_local_branch
    fi
    echo "vcpkg 当前操作分支是: $default_remote_branch"
    
    # 将本地分支重置为远程分支的最新状态
    echo "将本地 vcpkg ($default_remote_branch) 重置到 origin/$default_remote_branch 的最新状态..."
    git reset --hard "origin/$default_remote_branch"

    # 更新子模块 (vcpkg 可能使用)
    # echo "更新 vcpkg 子模块..."
    # git submodule update --init --recursive

    # 运行 bootstrap 脚本
    echo "重新引导 vcpkg..."
    ./bootstrap-vcpkg.sh -disableMetrics
    cd .. # 返回到 CPP_PROJECT_DIR
fi
export VCPKG_ROOT=$(pwd)/$VCPKG_DIR_NAME # 确保路径正确
# 对于 Linux Jenkins 代理，使用 Linux triplet
export VCPKG_DEFAULT_TRIPLET=x64-linux
echo "VCPKG_ROOT 设置为 $VCPKG_ROOT"
echo "VCPKG_DEFAULT_TRIPLET 设置为 $VCPKG_DEFAULT_TRIPLET"

# 2. 使用 vcpkg 安装依赖项
# 这些是 C++ 项目 README 中提到的库
# Asio 是 Crow 的依赖项，vcpkg 会自动处理。
echo "正在通过 vcpkg 安装依赖项: crow, nlohmann-json, asio..."
# 清理任何可能失败的先前安装 (可选，但有时有帮助)
# $VCPKG_ROOT/vcpkg remove crow nlohmann-json asio --triplet $VCPKG_DEFAULT_TRIPLET --recurse || echo "没有旧包需要移除，或者移除时出错。"
# 重新安装
$VCPKG_ROOT/vcpkg install crow nlohmann-json asio --triplet $VCPKG_DEFAULT_TRIPLET

# 3. 使用 CMake 配置和构建
echo "正在使用 CMake 配置 C++ 项目..."
mkdir -p build
cd build

# 确保您的 CMakeLists.txt 与 Linux 构建兼容。
# CMAKE_TOOLCHAIN_FILE 告诉 CMake 使用 vcpkg 查找包。
# VCPKG_TARGET_TRIPLET 指定 vcpkg 的目标体系结构。
cmake .. -DCMAKE_BUILD_TYPE=Release \
         -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake \
         -DVCPKG_TARGET_TRIPLET=$VCPKG_DEFAULT_TRIPLET
         # 如果需要，可以添加 -G "Unix Makefiles"，但在 Linux 上通常默认即可

echo "正在使用 make 构建 C++ 项目..."
make -j$(nproc) # 使用所有可用的处理器核心以加快编译速度

cd .. # 返回到 C++ 项目根目录 (TaskAPI/)
echo "构建完成。可执行文件应位于 $(pwd)/build/task_api"

# 4. 停止任何先前运行的 C++ API 实例
# 使用 pkill 按名称查找并终止进程。
# 名称 'task_api' 来自 CMakeLists.txt 中的 add_executable(task_api main.cpp)
echo "尝试停止任何先前运行的 'task_api' 实例..."
pkill -f ./build/task_api || echo "'task_api' 进程未找到或已停止。"
sleep 2 # 等待片刻以确保进程终止

# 5. 运行 C++ 应用程序
# 可执行文件是 'task_api' (在 CMakeLists.txt 中定义)，位于 'build' 目录下。
# 从项目根目录运行它，以便它可以按代码中的预期在当前工作目录找到/创建 tasks.json。
echo "正在启动 C++ TaskAPI 服务器..."
nohup ./build/task_api > task_api_server.log 2>&1 &

# 检查进程是否已启动 (可选, 基本检查)
sleep 5 # 给服务器一点启动时间
if pgrep -f "./build/task_api"; then
    echo "C++ TaskAPI 服务器已成功启动。PID: $(pgrep -f "./build/task_api")"
    echo "请检查 '$(pwd)/task_api_server.log' 文件以获取日志。"
else
    echo "错误：C++ TaskAPI 服务器启动失败。请检查 '$(pwd)/task_api_server.log' 和构建日志。"
    # 可选: 输出日志文件内容，以便在 Jenkins 中轻松调试
    if [ -f "task_api_server.log" ]; then
        echo "--- task_api_server.log 内容 ---"
        cat task_api_server.log
        echo "--- 日志内容结束 ---"
    fi
    exit 1
fi

echo "--- C++ 后端 (TaskAPI) CI/CD 脚本执行完毕 ---"